#ifndef LOG_BUF_H
#define LOG_BUF_H

#include <iostream>
#include <algorithm>
#include "log_message_pool.h"
#include "log_monitor.h"
#include "utils/mutex.hpp"
#include "utils/lock.hpp"

namespace vpm
{
	namespace log 
	{
		namespace detail
		{

			class LogBuf : public std::streambuf 
			{
			public:
				LogBuf( int loggerType):m_loggerType(loggerType)
				{		
					LogMessageBlock * pLogMsg = LogMonitor::instance().message_pool().require_message_block(m_loggerType);
					//pLogMsg->logger_type(m_loggerType);//bad way to set the logger type, should change the message pool
					setp(LogMessageBlockAccess::get_buffer(*pLogMsg).begin(), LogMessageBlockAccess::get_buffer(*pLogMsg).end());		
				}

				virtual ~LogBuf()
				{
				}

				int sync ()
				{		
					//std::copy(pbase(),pptr(),std::ostream_iterator<char>(std::cout));
					LogMessageBlock * pLogMsg  = (LogMessageBlock*) pbase();
					pLogMsg->wt_ptr((int)(this->pptr() - pbase()));
					*(pptr()) = 0;
					if (pLogMsg->length() > 0)
					{	
						assert(pLogMsg->length()> 0);
						LogMonitor::instance().post_message(pLogMsg);			
						LogMessageBlock * pNewLogMsg = LogMonitor::instance().message_pool().require_message_block(m_loggerType);
						setp(LogMessageBlockAccess::get_buffer(*pNewLogMsg).begin(), 
                                LogMessageBlockAccess::get_buffer(*pNewLogMsg).end());				
					}

					return 0; 
				}

				int overflow(int c)
				{
					sync();
					if (c != EOF) 
					{
						*pptr() = static_cast<unsigned char>(c);
						pbump(1);
					}
					return 0;
				}

				// Defining xsputn is an optional optimization.
				// (streamsize was recently added to ANSI C++, not portable yet.)
				// 	std::streamsize xsputn(const char *_Ptr, std::streamsize _Count)
				// 	{
				// 		return _Count;
				// 	}

			private:	
				int m_loggerType;	
			};
		}
	}
}

#endif // 
  
 

